package org.wdcode.common.codec;

import java.io.InputStream;

import javax.crypto.Cipher;
import org.wdcode.common.constants.EncryptConstants;
import org.wdcode.common.nio.StreamChannel;
import org.wdcode.common.params.WdCommonParams;
import org.wdcode.common.util.StringUtil;

/**
 * 加密类
 * @author WD
 * @since JDK6
 * @version 1.0 2010-06-22
 */
public final class Encrypt extends BaseCrypt {
	/**
	 * 加密字符串
	 * @param text 要加密的字符串
	 * @return 加密后的字节数组
	 */
	public final static byte[] encrypt(String text) {
		return encrypt(StringUtil.toBytes(text));
	}
	
	/**
	 * 加密字符串
	 * @param in 要加密的输入流
	 * @return 加密后的字节数组
	 */
	public final static byte[] encrypt(InputStream in) {
		return encrypt(StreamChannel.read(in));
	}
	
	/**
	 * 加密字符串
	 * @param b 要加密的字节数组
	 * @return 加密后的字节数组
	 */
	public final static byte[] encrypt(byte[] b) {
		// 判断加密方式
		if (EncryptConstants.ALGO_AES.equals(WdCommonParams.getEncryptAlgo())) {
			// AES加密
			return aes(b);
		} else if (EncryptConstants.ALGO_DES.equals(WdCommonParams.getEncryptAlgo())) {
			// DES加密
			return des(b);
		} else if (EncryptConstants.ALGO_RC2.equals(WdCommonParams.getEncryptAlgo())) {
			// RC2加密
			return rc2(b);
		} else if (EncryptConstants.ALGO_RC4.equals(WdCommonParams.getEncryptAlgo())) {
			// RC4加密
			return rc4(b);
		}
		// 默认返回AES
		return aes(b);
	}
	
	/**
	 * 加密字符串
	 * @param text 要加密的字符串
	 * @return 加密后的hex字符串
	 */
	public final static String encryptHex(String text) {
		return encryptHex(StringUtil.toBytes(text));
	}
	
	/**
	 * 加密字符串
	 * @param in 要加密的输入流
	 * @return 加密后的hex字符串
	 */
	public final static String encryptHex(InputStream in) {
		return encryptHex(StreamChannel.read(in));
	}
	
	/**
	 * 加密字符串
	 * @param b 要加密的字节数组
	 * @return 加密后的hex字符串
	 */
	public final static String encryptHex(byte[] b) {
		return Encode.hex(encrypt(b));
	}
	
	/**
	 * 加密字符串
	 * @param text 要加密的字符串
	 * @return 加密后的base64字符串
	 */
	public final static String encryptBase64(String text) {
		return encryptBase64(StringUtil.toBytes(text));
	}
	
	/**
	 * 加密字符串
	 * @param in 要加密的输入流
	 * @return 加密后的base64字符串
	 */
	public final static String encryptBase64(InputStream in) {
		return encryptBase64(StreamChannel.read(in));
	}
	
	/**
	 * 加密字符串
	 * @param b 要加密的字节数组
	 * @return 加密后的base64字符串
	 */
	public final static String encryptBase64(byte[] b) {
		return Encode.base64(encrypt(b));
	}

	/**
	 * 可逆的加密算法 DES算法
	 * @param text 需要加密的字符串
	 * @return 返回加密后的字节数组
	 */
	public final static byte[] des(String text) {
		return des(StringUtil.toBytes(text));
	}
	
	/**
	 * 可逆的加密算法 DES算法
	 * @param in 需要加密的输入流
	 * @return 返回加密后的字节数组
	 */
	public final static byte[] des(InputStream in) {
		return des(StreamChannel.read(in));
	}
	
	/**
	 * 可逆的加密算法 DES算法
	 * @param b 需要加密的字节数组
	 * @return 返回加密后的字节数组
	 */
	public final static byte[] des(byte[] b) {
		return encrypt(b, KEY, 0, DES_LENGTH, EncryptConstants.ALGO_DES);
	}
	
	/**
	 * 可逆的加密算法 DES算法
	 * @param text 需要加密的字符串
	 * @return 返回加密后的hex字符串
	 */
	public final static String desHex(String text) {
		return desHex(StringUtil.toBytes(text));
	}
	
	/**
	 * 可逆的加密算法 DES算法
	 * @param in 需要加密的输入流
	 * @return 返回加密后的hex字符串
	 */
	public final static String desHex(InputStream in) {
		return desHex(StreamChannel.read(in));
	}
	
	/**
	 * 可逆的加密算法 DES算法
	 * @param b 需要加密的字节数组
	 * @return 返回加密后的hex字符串
	 */
	public final static String desHex(byte[] b) {
		return Encode.hex(des(b));
	}
	
	/**
	 * 可逆的加密算法 DES算法
	 * @param text 需要加密的字符串
	 * @return 返回加密后的base64字符串
	 */
	public final static String desBase64(String text) {
		return desBase64(StringUtil.toBytes(text));
	}
	
	/**
	 * 可逆的加密算法 DES算法
	 * @param in 需要加密的输入流
	 * @return 返回加密后的base64字符串
	 */
	public final static String desBase64(InputStream in) {
		return desBase64(StreamChannel.read(in));
	}
	
	/**
	 * 可逆的加密算法 DES算法
	 * @param b 需要加密的字节数组
	 * @return 返回加密后的base64字符串
	 */
	public final static String desBase64(byte[] b) {
		return Encode.base64(des(b));
	}

	/**
	 * 可逆的加密算法 AES算法
	 * @param text 需要加密的字符串
	 * @return 返回加密后的字节数组
	 */
	public final static byte[] aes(String text) {
		return aes(StringUtil.toBytes(text));
	}
	
	/**
	 * 可逆的加密算法 AES算法
	 * @param in 需要加密的输入流
	 * @return 返回加密后的字节数组
	 */
	public final static byte[] aes(InputStream in) {
		return aes(StreamChannel.read(in));
	}
	
	/**
	 * 可逆的加密算法 AES算法
	 * @param b 需要加密的字节数组
	 * @return 返回加密后的字节数组
	 */
	public final static byte[] aes(byte[] b) {
		return encrypt(b, KEY, 0, AES_LENGTH, EncryptConstants.ALGO_AES);
	}
	
	/**
	 * 可逆的加密算法 AES算法
	 * @param text 需要加密的字符串
	 * @return 返回加密后的hex字符串
	 */
	public final static String aesHex(String text) {
		return aesHex(StringUtil.toBytes(text));
	}
	
	/**
	 * 可逆的加密算法 AES算法
	 * @param in 需要加密的输入流
	 * @return 返回加密后的hex字符串
	 */
	public final static String aesHex(InputStream in) {
		return aesHex(StreamChannel.read(in));
	}
	
	/**
	 * 可逆的加密算法 AES算法
	 * @param b 需要加密的字节数组
	 * @return 返回加密后的hex字符串
	 */
	public final static String aesHex(byte[] b) {
		return Encode.hex(aes(b));
	}
	
	/**
	 * 可逆的加密算法 AES算法
	 * @param text 需要加密的字符串
	 * @return 返回加密后的base64字符串
	 */
	public final static String aesBase64(String text) {
		return aesBase64(StringUtil.toBytes(text));
	}
	
	/**
	 * 可逆的加密算法 AES算法
	 * @param in 需要加密的输入流
	 * @return 返回加密后的base64字符串
	 */
	public final static String aesBase64(InputStream in) {
		return aesBase64(StreamChannel.read(in));
	}
	
	/**
	 * 可逆的加密算法 AES算法
	 * @param b 需要加密的字节数组
	 * @return 返回加密后的base64字符串
	 */
	public final static String aesBase64(byte[] b) {
		return Encode.base64(aes(b));
	}

	/**
	 * 可逆的加密算法 RC2算法
	 * @param text 需要加密的字符串
	 * @return 返回加密后的字节数组
	 */
	public final static byte[] rc2(String text) {
		return rc2(StringUtil.toBytes(text));
	}
	
	/**
	 * 可逆的加密算法 RC2算法
	 * @param in 需要加密的输入流
	 * @return 返回加密后的字节数组
	 */
	public final static byte[] rc2(InputStream in) {
		return rc2(StreamChannel.read(in));
	}
	
	/**
	 * 可逆的加密算法 RC2算法
	 * @param b 需要加密的字节数组
	 * @return 返回加密后的字节数组 
	 */
	public final static byte[] rc2(byte[] b) {
		return encrypt(b, KEY, 0, RC2_LENGTH, EncryptConstants.ALGO_RC2);
	}
	
	/**
	 * 可逆的加密算法 RC2算法
	 * @param text 需要加密的字符串
	 * @return 返回加密后的hex字符串
	 */
	public final static String rc2Hex(String text) {
		return rc2Hex(StringUtil.toBytes(text));
	}
	
	/**
	 * 可逆的加密算法 RC2算法
	 * @param in 需要加密的输入流
	 * @return 返回加密后的hex字符串
	 */
	public final static String rc2Hex(InputStream in) {
		return rc2Hex(StreamChannel.read(in));
	}
	
	/**
	 * 可逆的加密算法 RC2算法
	 * @param b 需要加密的字节数组
	 * @return 返回加密后的hex字符串
	 */
	public final static String rc2Hex(byte[] b) {
		return Encode.hex(rc2(b));
	}
	
	/**
	 * 可逆的加密算法 RC2算法
	 * @param text 需要加密的字符串
	 * @return 返回加密后的base64字符串
	 */
	public final static String rc2Base64(String text) {
		return rc2Base64(StringUtil.toBytes(text));
	}
	
	/**
	 * 可逆的加密算法 RC2算法
	 * @param in 需要加密的输入流
	 * @return 返回加密后的base64字符串
	 */
	public final static String rc2Base64(InputStream in) {
		return rc2Base64(StreamChannel.read(in));
	}
	
	/**
	 * 可逆的加密算法 RC2算法
	 * @param b 需要加密的字节数组
	 * @return 返回加密后的base64字符串
	 */
	public final static String rc2Base64(byte[] b) {
		return Encode.base64(rc2(b));
	}

	/**
	 * 可逆的加密算法 RC4算法
	 * @param text 需要加密的字符串
	 * @return 返回加密后的字节数组
	 */
	public final static byte[] rc4(String text) {
		return rc4(StringUtil.toBytes(text));
	}
	
	/**
	 * 可逆的加密算法 RC4算法
	 * @param in 需要加密的输入流
	 * @return 返回加密后的字节数组
	 */
	public final static byte[] rc4(InputStream in) {
		return rc4(StreamChannel.read(in));
	}
	
	/**
	 * 可逆的加密算法 RC4算法
	 * @param b 需要加密的字节数组
	 * @return 返回加密后的字节数组 
	 */
	public final static byte[] rc4(byte[] b) {
		return encrypt(b, KEY, 0, RC4_LENGTH, EncryptConstants.ALGO_RC4);
	}
	
	/**
	 * 可逆的加密算法 RC4算法
	 * @param text 需要加密的字符串
	 * @return 返回加密后的hex字符串
	 */
	public final static String rc4Hex(String text) {
		return rc4Hex(StringUtil.toBytes(text));
	}
	
	/**
	 * 可逆的加密算法 RC4算法
	 * @param in 需要加密的输入流
	 * @return 返回加密后的hex字符串
	 */
	public final static String rc4Hex(InputStream in) {
		return rc4Hex(StreamChannel.read(in));
	}
	
	/**
	 * 可逆的加密算法 RC4算法
	 * @param b 需要加密的字节数组
	 * @return 返回加密后的hex字符串
	 */
	public final static String rc4Hex(byte[] b) {
		return Encode.hex(rc4(b));
	}
	
	/**
	 * 可逆的加密算法 RC4算法
	 * @param text 需要加密的字符串
	 * @return 返回加密后的base64字符串
	 */
	public final static String rc4Base64(String text) {
		return rc4Base64(StringUtil.toBytes(text));
	}
	
	/**
	 * 可逆的加密算法 RC4算法
	 * @param in 需要加密的输入流
	 * @return 返回加密后的base64字符串
	 */
	public final static String rc4Base64(InputStream in) {
		return rc4Base64(StreamChannel.read(in));
	}
	
	/**
	 * 可逆的加密算法 RC4算法
	 * @param b 需要加密的字节数组
	 * @return 返回加密后的base64字符串
	 */
	public final static String rc4Base64(byte[] b) {
		return Encode.base64(rc4(b));
	}

	/**
	 * 加密字符串
	 * @param text 要加密的字符串
	 * @param key 加密密钥Key 长度有限制 DSE 为8位 ASE 为16位
	 * @param offset 偏移从第几位开始
	 * @param len 长度一共几位
	 * @param algorithm 算法
	 * @return 加密后的字节数组
	 */
	private static byte[] encrypt(byte[] b, byte[] key, int offset, int len, String algorithm) {
		return doFinal(b, key, offset, len, algorithm, Cipher.ENCRYPT_MODE);
	}

	/**
	 * 私有构造
	 */
	private Encrypt() {}
}
